/*
 * $Id: MemoryPool.h,v 1.4 2005-04-24 08:17:08 bacon Exp $
 */

#ifndef _XPP_BAS_MEMORYPOOL_CLASS_
#define _XPP_BAS_MEMORYPOOL_CLASS_

#include <xp/types.h>
#include <xp/macros.h>
#include <xp/bas/assert.h>
#include <xpp/Uncopyable.h>

namespace xpp
{
	namespace bas 
	{

		//
		// allocator for fixed-size data
		//

		class MemoryPool: public Uncopyable 
		{
		public:
			enum {
				DEFAULT_BLOCK_SIZE = 128
			};

			MemoryPool (
				xp_size_t datum_size, 
				xp_size_t block_size = DEFAULT_BLOCK_SIZE);
			~MemoryPool ();

			void* allocate ();
			void  dispose (void* ptr);
			void  dispose ();

			inline bool isEnabled () const
			{
				return this->datum_size > 0 && this->block_size > 0;
			}
			inline bool isDisabled () const
			{
				return this->datum_size <= 0 || this->block_size <= 0;
			}

			inline xp_size_t datumSize () const
			{
				return this->datum_size;
			}
			inline xp_size_t blockSize () const
			{
				return this->block_size;
			}
			inline void setBlockSize (xp_size_t blockSize) 
			{
				this->block_size = blockSize;
			}

#ifdef XP_DEBUG_VERBOSE
			xp_size_t  nalloc;
			xp_size_t  navail;
#endif

		protected:
			struct Block 
			{
				Block*  next;
				//xp_byte_t data[0];
			};
			struct Chain 
			{
				Chain* next;	
			};

			Block* mp_blocks;
			Chain* free_list;
			xp_size_t datum_size;
			xp_size_t block_size;

			void add_block ();
		};
	}
}

#endif

